import sys
import time

from DrissionPage import ChromiumPage
import pymysql
import pyautogui
from bs4 import BeautifulSoup
import re
import logging
from logging.handlers import TimedRotatingFileHandler
from tqdm import tqdm

log_file = 'douyin_video_comment.log'

# 创建一个处理日志的处理器
log_handler = logging.FileHandler(log_file)
log_formatter = logging.Formatter('%(asctime)s - %(levelname)s - %(message)s')
log_handler.setFormatter(log_formatter)
log_handler.setLevel(logging.INFO)

# 获取日志记录器并添加处理器
logger = logging.getLogger()
logger.addHandler(log_handler)
logger.setLevel(logging.INFO)
# 设置超时时间为10分钟
timeout = 5 * 60
# 获取视频ID，转换为整数
# try:
#     videoid = int(input('从第几条视频开始获取评论: ')) - 1
# except ValueError:
#     print("输入无效，请输入一个整数。三秒后程序自动结束,请重新运行程序")
#     time.sleep(3)
#     exit(1)
videoid_str = input('请输入上次断掉的id,直接回车默认是0')
if videoid_str == '':
    videoid = 0
else:
    videoid = int(videoid_str)


def filter_comment(comment):
    """
    过滤评论中的非法字符
    """
    # 使用正则表达式替换非法字符为空字符串
    filtered_comment = re.sub(r'[^\u4e00-\u9fa5a-zA-Z0-9.,!?;:()\'"\-_ ]', '', comment)
    return filtered_comment


insert_sql = '''
    UPDATE 抖音视频表
    SET 视频发布时间_2=%s
    WHERE ID = %s
    '''

DB_CONFIG = {
    'host': 'rm-2zea30h4sh8g15zd1ho.mysql.rds.aliyuncs.com',
    'port': 3306,
    'user': "root",
    'password': 'Ds2024@()833429',
    'database': "douyinpinglun"
}
mydb = pymysql.connect(**DB_CONFIG)
cursor = mydb.cursor()
driver = ChromiumPage()
driver.set.window.max()
print('数据库连接成功')

start_date = input('请输入起始日期,如2024-12-12 :')
if not start_date:
    start_date = '1972-12-12'
end_date = input('请输入结束日期,如2024-12-16 :')
if not end_date:
    end_date = '2030-12-12'
cursor.execute(
    "select id,视频链接,评论量 from 抖音视频表 where 视频发布时间_2 between %s and %s and 是否下架 is null and id > %s order by id",
    (start_date, end_date, videoid,))
videoid_url_tuples = cursor.fetchall()
print(f'共{len(videoid_url_tuples)}条视频')

for videoid_url in videoid_url_tuples:
    # 关联视频表id
    videoid = videoid_url[0]
    print(f'当前正在爬取id为{videoid}的视频')
    logger.info(f'当前正在爬取id为{videoid}的视频')
    # 视频链接
    video_url = videoid_url[1]
    # 评论数量
    comment_number = int(videoid_url[2])
    driver.get(video_url)
    # 爬取视频时间--------------------------------------------------------------------------------------------------------
    driver.wait(7)
    try:
        if driver.ele('x://*[@id="douyin-right-container"]/div[2]/div/div/p[1]').text == '你要观看的视频不存在':
            print('该视频已下架')
            cursor.execute(f'delete from 抖音视频表 where id={videoid}')
            mydb.commit()
            print('事务已提交')
            continue
    except Exception as e:
        video_date_text = driver.ele(
            'xpath://*[@id="douyin-right-container"]/div[2]/div/div/div[1]/div[3]/div/div[2]/div[2]/span').text
        video_date = video_date_text.replace('发布时间：', '')
        print(video_date)

        cursor.execute(insert_sql, (video_date, videoid))
        mydb.commit()
        pass

    try:
        video_date_text = driver.ele(
            'xpath://*[@id="douyin-right-container"]/div[2]/div/div/div[1]/div[3]/div/div[2]/div[2]/span').text
        video_date = video_date_text.replace('发布时间：', '')
    except:
        try:
            driver.ele('.jp8u3iov').click()
            video_date_text = driver.ele('.__VJux97').text
            # 计算日期部分的起始和结束位置
            start_index = video_date_text.find("：") + 1  # 找到“：”的位置，并加1得到日期的起始位置
            end_index = start_index + 10  # 日期长度为10位

            # 使用切片提取日期
            video_date = video_date_text[start_index:end_index]
        except:
            video_date = driver.ele('x://*[@id="video-info-wrap"]/div[1]/div[1]/div[2]/span').text.split('·')
            print(video_date)
    print(video_date)

    cursor.execute(insert_sql, (video_date, videoid))
    mydb.commit()
    try:
        if pyautogui.locateOnScreen(r'E:\pythonproject\douyingpinglun\pictures\no_video.png', confidence=0.7):
            print('该视频已下架')
            insert_sql = '''
                UPDATE 抖音视频表
                SET 是否下架=%s
                WHERE ID = %s;
                '''
            cursor.execute(insert_sql, ('已下架', videoid))
            mydb.commit()
            continue
    except:
        pass
    # 评论
    try:
        comment = driver.ele(
            'xpath://*[@id="douyin-right-container"]/div[2]/div/div/div[1]/div[3]/div/div[2]/div[1]/div[2]/span').text
    except:
        continue
    if '首评' in comment:
        continue
    try:
        if '万' in comment:
            pnumber2 = int(float(comment.split('万')[0]) * 10000)
        else:
            pnumber2 = int(comment)
    except:
        continue
    # 每日更新用,如果评论数没变,就跳过---------------------------------------------------------------------------------------------------------------------------------------------------------
    # if comment_number == pnumber2:
    #     print(f'{comment_number} == {pnumber2}')
    #     print('评论数没变,跳过')
    #     continue
    # 点赞
    dnumber1 = 0
    dianzhan = driver.ele(
        'xpath://*[@id="douyin-right-container"]/div[2]/div/div/div[1]/div[3]/div/div[2]/div[1]/div[1]/span').text
    try:
        if '万' in dianzhan:
            dnumber1 = int(float(dianzhan.split('万')[0]) * 10000)
        else:
            dnumber1 = int(dianzhan)
    except:
        pass

    # 收藏
    snumber3 = 0
    collect = driver.ele(
        'xpath://*[@id="douyin-right-container"]/div[2]/div/div/div[1]/div[3]/div/div[2]/div[1]/div[3]/span').text
    try:
        if '万' in collect:
            snumber3 = int(float(collect.split('万')[0]) * 10000)
        else:
            snumber3 = int(collect)
    except:
        pass

    # 转发
    znumber4 = 0
    share = driver.ele(
        'xpath://*[@id="douyin-right-container"]/div[2]/div/div/div[1]/div[3]/div/div[2]/div[1]/div[4]/span').text
    try:
        if '万' in share:
            znumber4 = int(float(share.split('万')[0]) * 10000)
        else:
            znumber4 = int(share)
    except:
        pass
    if pnumber2 == 0:
        continue
    video_date_text = driver.ele(
        'xpath://*[@id="douyin-right-container"]/div[2]/div/div/div[1]/div[3]/div/div[2]/div[2]/span').text
    video_date = video_date_text.replace('发布时间：', '')
    insert_sql = '''
    UPDATE 抖音视频表
    SET 点赞量 = %s, 评论量 = %s, 收藏量 = %s, 转发量 = %s,视频发布时间_2=%s
    WHERE ID = %s;
    '''
    cursor.execute(insert_sql, (dnumber1, pnumber2, snumber3, znumber4, video_date, videoid))
    mydb.commit()

    pyautogui.moveTo(1688, 904)
    start_time = time.time()
    while True:
        if time.time() - start_time > timeout:
            break
        try:
            more_location = pyautogui.locateOnScreen(r'pictures/reply.png', confidence=0.8)
            pyautogui.click(more_location)
            driver.wait(0.8)
        except:
            try:
                more_comment_location = pyautogui.locateOnScreen(r'pictures/more.png', confidence=0.77)
                pyautogui.click(more_comment_location)
                driver.wait(0.4)
            except:
                try:
                    if pyautogui.locateOnScreen(r'E:\pythonproject\douyingpinglun\pictures\no_more_comment.png',
                                                confidence=0.8):
                        break
                except:
                    pass
                try:
                    if pyautogui.locateOnScreen(r'E:\pythonproject\douyingpinglun\pictures\no_more_comment2.png',
                                                confidence=0.8):
                        break
                except:
                    pass
                try:
                    if pyautogui.locateOnScreen(r'E:\pythonproject\douyingpinglun\pictures\no_comment3.png',
                                                confidence=0.8):
                        break
                except:
                    pass
                try:
                    if pyautogui.locateOnScreen(r'E:\pythonproject\douyingpinglun\pictures\no_comment4.png',
                                                confidence=0.8):
                        break
                except:
                    pass
        pyautogui.scroll(-300)
        driver.wait(0.8)

    comment_bolcks = driver.ele('.Rwb9ssMc comment-mainContent').eles('.UuCzPLbi')
    # 各个评论对,也就是一块块评论块
    for comment_bolck_index, comment_block in enumerate(comment_bolcks):
        html_content_text = comment_block.html
        soup = BeautifulSoup(html_content_text, 'lxml')
        comments = soup.findAll('div', class_='Vrj4Q3zT fiDvPS80')
        # 评论块里的每一行
        comment_history = set()
        for comment_item in comments:
            authors = comment_item.findAll('a', class_='uz1VJwFY')
            # 用户昵称
            author_name = authors[0].get_text(strip=True)
            print(f'作者:{author_name}')
            author_name = filter_comment(author_name)
            # 评论内容
            try:
                comment_text = comment_item.find('span', class_='WFJiGxr7').get_text(strip=True)
            except:
                comment_text = None
                continue
            print(f'评论:{comment_text}')
            # 过滤评论内容
            comment_text = filter_comment(comment_text)
            if not comment_text or comment_text in comment_history:
                continue
            # 评论时间和地点
            comment_history.add(comment_text)
            comment_time_space = comment_item.find('div', class_='fJhvAqos').get_text(strip=True)
            comment_time = comment_time_space.split('·')[0]
            try:
                comment_space = comment_time_space.split('·')[1]
            except:
                comment_space = None
            print(f'时间:{comment_time}')
            print(f'地点:{comment_space}')
            # 用户点赞数
            comment_support_number = comment_item.find('p', class_='xZhLomAs').get_text(strip=True)
            if '万' in comment_support_number:
                comment_support_number = int(float(comment_support_number.split('万')[0]) * 10000)
            else:
                comment_support_number = int(comment_support_number)

            print(f'点赞数:{comment_support_number}')
            print(f'问答对编号:{comment_bolck_index}')
            # 插入 SQL 语句
            insert_sql = '''
                INSERT INTO 视频评论表 
                (关联视频表id, 评论内容, 用户昵称, 评论点赞数, 评论时间, 评论地点, 问答对编号)
                VALUES (%s, %s, %s, %s, %s, %s, %s);
                '''
            # 执行插入操作
            try:
                cursor.execute(insert_sql, (
                    videoid, comment_text, author_name, comment_support_number, comment_time, comment_space,
                    comment_bolck_index))
                mydb.commit()  # 提交事务
            except:
                pass

cursor.close()
mydb.close()
#
# driver.get('https://live.douyin.com/889398542120')
# driver.set.window.max()
